#ifndef __SUBREACTOR_H__
#define __SUBREACTOR_H__

#include <iostream>
#include <vector>
#include <map>
#include <memory>
#include <functional>
#include <mutex>
#include <thread>
#include <sys/epoll.h>

class TcpConnection;

class SubReactor
{
    using TcpConnectionPtr = std::shared_ptr<TcpConnection>;
    using TcpConnectionCallback = std::function<void(const TcpConnectionPtr &)>;
    using Functor = std::function<void()>;
    
public:
    SubReactor();
    ~SubReactor();
    
    void start();
    void stop();
    void loop();
    void unloop();
    
    void addConnection(int connfd);
    
    void setNewConnectionCallback(const TcpConnectionCallback &cb);
    void setMessageCallback(const TcpConnectionCallback &cb);
    void setCloseCallback(const TcpConnectionCallback &cb);
    
    void runInLoop(Functor &&cb);
    void wakeup();

    size_t getConnectionCount() { return _conns.size(); }
    
private:
    int createEpollFd();
    int createEventFd();
    void addEpollReadFd(int fd);
    void delEpollReadFd(int fd);
    void waitEpollFd();
    void handleMessage(int fd);
    void handleRead();
    void doPengdingFunctors();
    
private:
    int _epfd;
    std::vector<struct epoll_event> _evtList;
    bool _isLooping;
    std::map<int, TcpConnectionPtr> _conns;
    
    int _evtfd;
    std::vector<Functor> _pendings;
    std::mutex _mutex;
    std::thread _subThread;
    
    TcpConnectionCallback _onNewConnection;
    TcpConnectionCallback _onMessage;
    TcpConnectionCallback _onClose;
};

#endif